from clasesPrincipales.Instruccion import Instruccion
from clasesPrincipales.ManagerInterruptor import Signal
from estados.Estados import Run, Wait
from planificacion.ListenCPU import ListenCPU
from threading import Thread
import time

class CPU(Thread):
    
###############################################################################################################

    #INICIALIZACION
    #La cpu es un threads, recibe al kernel, para q este le indique 
    #cuando detenerse
    def __init__(self, mmu, kernel) :
        Thread.__init__(self)
        self.pc = None # program counter(pcb)
        self.elKernel = kernel
        self.mmu = mmu
        self.current_pid = None # el proceso actual (number)
        self.listener = ListenCPU()
        self.registros = {'A': 0, 'B':0, 'C':0, 'D':0, 'E':0, 'F':0, 'G':0, 'H':0}


###############################################################################################################

    #METODOS
    def run(self):
        while self.elKernel.getRunning():                 
            if self.pc is not None:
                print('Se esta ejecutando: %s' % self.pc.getProgram().getName())
                result = self.mmu.get(self.pc)
                print ("el valor del get es ", result)
                self.definirTipoInstruccion(result)
            else:
                time.sleep(0.1) 
                

    def definirTipoInstruccion (self, instr):
        if instr.tipoInstruccion is Instruccion.CPU:
            print('[cpu]')
            self.ejecutarInstrCpu()
        elif instr.tipoInstruccion is Instruccion.IO:
            print('[io]')
            self.pc.setState(Wait())
            self.elKernel.managerInterruptor.interrupcion(Signal.IO_REQ)
        elif instr.tipoInstruccion is Instruccion.EXIT:
            print ('* Finalizo la ejecucion del programa: %s' % self.pc.getProgram().getName())
            self.pc= None
            self.elKernel.managerInterruptor.interrupcion(Signal.EXIT)
        else:
            self.elKernel.managerInterruptor.interrupcion(Signal.KILL)


    def ejecutarInstrCpu (self):
        if not self.elKernel.getKernelMode(): 
            self.pc.setState(Run())
            time.sleep(1)
            self.pc.aumentarInstruction()
            self.listener.propagarAviso()
